/*
 * Copyright (c) 2006-2018, RT-Thread Development Team
 *
 * SPDX-License-Identifier: Apache-2.0
 *
 * Change Logs:
 * Date           Author           Notes
 * 2019-07-06     heyuanjie87      the first version
 */

#include <stm32l4xx.h>
#include <rtdevice.h>
#include <rthw.h>

#ifdef BSP_USING_UART1
    #define USART1_RX_GPIO_CLK_ENABLE()      __HAL_RCC_GPIOA_CLK_ENABLE()
    #define USART1_TX_GPIO_CLK_ENABLE()      __HAL_RCC_GPIOA_CLK_ENABLE()

    /* Definition for USART1 Pins */
    #define USART1_TX_PIN                    GPIO_PIN_9
    #define USART1_TX_GPIO_PORT              GPIOA
    #define USART1_TX_AF                     GPIO_AF7_USART1
    #define USART1_RX_PIN                    GPIO_PIN_10
    #define USART1_RX_GPIO_PORT              GPIOA
    #define USART1_RX_AF                     GPIO_AF7_USART1

    #define USART1_RX_DMA_CHANNEL            DMA1_Channel5
    #define USART1_RX_DMA_REUQEST            DMA_REQUEST_2
    #define USART1_RX_DMA_IRQN               DMA1_Channel5_IRQn
    #define USART1_RX_DMA_IRQHandler         DMA1_Channel5_IRQHandler
#endif

#ifdef BSP_USING_UART2
    #define USART2_RX_GPIO_CLK_ENABLE()      __HAL_RCC_GPIOA_CLK_ENABLE()
    #define USART2_TX_GPIO_CLK_ENABLE()      __HAL_RCC_GPIOA_CLK_ENABLE()

    /* Definition for USART2 Pins */
    #define USART2_TX_PIN                    GPIO_PIN_2
    #define USART2_TX_GPIO_PORT              GPIOA
    #define USART2_TX_AF                     GPIO_AF7_USART2
    #define USART2_RX_PIN                    GPIO_PIN_3
    #define USART2_RX_GPIO_PORT              GPIOA
    #define USART2_RX_AF                     GPIO_AF7_USART2

    #define USART2_RX_DMA_CHANNEL            DMA1_Channel6
    #define USART2_RX_DMA_REUQEST            DMA_REQUEST_2
    #define USART2_RX_DMA_IRQN               DMA1_Channel6_IRQn
    #define USART2_RX_DMA_IRQHandler         DMA1_Channel6_IRQHandler
#endif

#ifdef BSP_USING_UART3
    #define USART3_RX_GPIO_CLK_ENABLE()      __HAL_RCC_GPIOC_CLK_ENABLE()
    #define USART3_TX_GPIO_CLK_ENABLE()      __HAL_RCC_GPIOC_CLK_ENABLE()

    /* Definition for USART3 Pins */
    #define USART3_TX_PIN                    GPIO_PIN_4
    #define USART3_TX_GPIO_PORT              GPIOC
    #define USART3_TX_AF                     GPIO_AF7_USART3
    #define USART3_RX_PIN                    GPIO_PIN_5
    #define USART3_RX_GPIO_PORT              GPIOC
    #define USART3_RX_AF                     GPIO_AF7_USART3

    #define USART3_RX_DMA_CHANNEL            DMA1_Channel3
    #define USART3_RX_DMA_REUQEST            DMA_REQUEST_2
    #define USART3_RX_DMA_IRQN               DMA1_Channel3_IRQn
    #define USART3_RX_DMA_IRQHandler         DMA1_Channel3_IRQHandler
#endif

#ifdef BSP_USING_LPUART1
    #define LPUART1_RX_GPIO_CLK_ENABLE()      __HAL_RCC_GPIOB_CLK_ENABLE()
    #define LPUART1_TX_GPIO_CLK_ENABLE()      __HAL_RCC_GPIOB_CLK_ENABLE()

    /* Definition for LPUART1 Pins */
    #define LPUART1_TX_PIN                    GPIO_PIN_11
    #define LPUART1_TX_GPIO_PORT              GPIOB
    #define LPUART1_TX_AF                     GPIO_AF8_LPUART1
    #define LPUART1_RX_PIN                    GPIO_PIN_10
    #define LPUART1_RX_GPIO_PORT              GPIOB
    #define LPUART1_RX_AF                     GPIO_AF8_LPUART1

    #define LPUART1_RX_DMA_CHANNEL            DMA2_Channel7
    #define LPUART1_RX_DMA_REUQEST            DMA_REQUEST_4
    #define LPUART1_RX_DMA_IRQN               DMA2_Channel7_IRQn
    #define LPUART1_RX_DMA_IRQHandler         DMA2_Channel7_IRQHandler
#endif

/**
* @brief UART MSP Initialization
*        This function configures the hardware resources used in this example:
*           - Peripheral's clock enable
*           - Peripheral's GPIO Configuration
*           - NVIC configuration for UART interrupt request enable
* @param huart: UART handle pointer
* @retval None
*/
void HAL_UART_MspInit(UART_HandleTypeDef *huart)
{
    GPIO_InitTypeDef  GPIO_InitStruct;

#if defined(BSP_USING_UART1)
    if (huart->Instance == USART1)
    {
        /*##-1- Enable peripherals and GPIO Clocks #################################*/
        /* Enable GPIO TX/RX clock */
        USART1_TX_GPIO_CLK_ENABLE();
        USART1_RX_GPIO_CLK_ENABLE();

        /* Enable USARTx clock */
        __HAL_RCC_USART1_CLK_ENABLE();

        /*##-2- Configure peripheral GPIO ##########################################*/
        /* UART TX GPIO pin configuration  */
        GPIO_InitStruct.Pin       = USART1_TX_PIN;
        GPIO_InitStruct.Mode      = GPIO_MODE_AF_PP;
        GPIO_InitStruct.Pull      = GPIO_PULLUP;
        GPIO_InitStruct.Speed     = GPIO_SPEED_FREQ_LOW;
        GPIO_InitStruct.Alternate = USART1_TX_AF;

        HAL_GPIO_Init(USART1_TX_GPIO_PORT, &GPIO_InitStruct);

        /* UART RX GPIO pin configuration  */
        GPIO_InitStruct.Pin = USART1_RX_PIN;
        GPIO_InitStruct.Alternate = USART1_RX_AF;

        HAL_GPIO_Init(USART1_RX_GPIO_PORT, &GPIO_InitStruct);
    }
#endif

#if defined(BSP_USING_UART2)
    if (huart->Instance == USART2)
    {
        /*##-1- Enable peripherals and GPIO Clocks #################################*/
        /* Enable GPIO TX/RX clock */
        USART2_TX_GPIO_CLK_ENABLE();
        USART2_RX_GPIO_CLK_ENABLE();

        /* Enable USARTx clock */
        __HAL_RCC_USART2_CLK_ENABLE();

        /*##-2- Configure peripheral GPIO ##########################################*/
        /* UART TX GPIO pin configuration  */
        GPIO_InitStruct.Pin       = USART2_TX_PIN;
        GPIO_InitStruct.Mode      = GPIO_MODE_AF_PP;
        GPIO_InitStruct.Pull      = GPIO_PULLUP;
        GPIO_InitStruct.Speed     = GPIO_SPEED_FREQ_LOW;
        GPIO_InitStruct.Alternate = USART2_TX_AF;

        HAL_GPIO_Init(USART2_TX_GPIO_PORT, &GPIO_InitStruct);

        /* UART RX GPIO pin configuration  */
        GPIO_InitStruct.Pin = USART2_RX_PIN;
        GPIO_InitStruct.Alternate = USART2_RX_AF;

        HAL_GPIO_Init(USART2_RX_GPIO_PORT, &GPIO_InitStruct);
    }
#endif

#if defined(BSP_USING_UART3)
    if (huart->Instance == USART3)
    {
        /*##-1- Enable peripherals and GPIO Clocks #################################*/
        /* Enable GPIO TX/RX clock */
        USART3_TX_GPIO_CLK_ENABLE();
        USART3_RX_GPIO_CLK_ENABLE();

        /* Enable USARTx clock */
        __HAL_RCC_USART3_CLK_ENABLE();

        /*##-2- Configure peripheral GPIO ##########################################*/
        /* UART TX GPIO pin configuration  */
        GPIO_InitStruct.Pin       = USART3_TX_PIN;
        GPIO_InitStruct.Mode      = GPIO_MODE_AF_PP;
        GPIO_InitStruct.Pull      = GPIO_PULLUP;
        GPIO_InitStruct.Speed     = GPIO_SPEED_FREQ_LOW;
        GPIO_InitStruct.Alternate = USART3_TX_AF;

        HAL_GPIO_Init(USART3_TX_GPIO_PORT, &GPIO_InitStruct);

        /* UART RX GPIO pin configuration  */
        GPIO_InitStruct.Pin = USART3_RX_PIN;
        GPIO_InitStruct.Alternate = USART3_RX_AF;

        HAL_GPIO_Init(USART3_RX_GPIO_PORT, &GPIO_InitStruct);
    }
#endif

#if defined(BSP_USING_LPUART1)
    if (huart->Instance == LPUART1)
    {
        /*##-1- Enable peripherals and GPIO Clocks #################################*/
        /* Enable GPIO TX/RX clock */
        LPUART1_TX_GPIO_CLK_ENABLE();
        LPUART1_RX_GPIO_CLK_ENABLE();

        /* Enable USARTx clock */
        __HAL_RCC_LPUART1_CLK_ENABLE();

        /*##-2- Configure peripheral GPIO ##########################################*/
        /* UART TX GPIO pin configuration  */
        GPIO_InitStruct.Pin       = LPUART1_TX_PIN;
        GPIO_InitStruct.Mode      = GPIO_MODE_AF_PP;
        GPIO_InitStruct.Pull      = GPIO_PULLUP;
        GPIO_InitStruct.Speed     = GPIO_SPEED_FREQ_LOW;
        GPIO_InitStruct.Alternate = LPUART1_TX_AF;

        HAL_GPIO_Init(LPUART1_TX_GPIO_PORT, &GPIO_InitStruct);

        /* UART RX GPIO pin configuration  */
        GPIO_InitStruct.Pin       = LPUART1_RX_PIN;
        GPIO_InitStruct.Alternate = LPUART1_RX_AF;

        HAL_GPIO_Init(LPUART1_RX_GPIO_PORT, &GPIO_InitStruct);
    }
#endif
}

/**
* @brief UART MSP De-Initialization
*        This function frees the hardware resources used in this example:
*          - Disable the Peripheral's clock
*          - Revert GPIO and NVIC configuration to their default state
* @param huart: UART handle pointer
* @retval None
*/
void HAL_UART_MspDeInit(UART_HandleTypeDef *huart)
{
#if defined(BSP_USING_UART1)
    if (huart->Instance == USART1)
    {
        /*##-1- Reset peripherals ##################################################*/
        __HAL_RCC_USART1_FORCE_RESET();
        __HAL_RCC_USART1_RELEASE_RESET();

        /*##-2- Disable peripherals and GPIO Clocks #################################*/
        /* Configure UART Tx as alternate function  */
        HAL_GPIO_DeInit(USART1_TX_GPIO_PORT, USART1_TX_PIN);
        /* Configure UART Rx as alternate function  */
        HAL_GPIO_DeInit(USART1_RX_GPIO_PORT, USART1_RX_PIN);

        HAL_NVIC_DisableIRQ(USART1_IRQn);
    }
#endif

#if defined(BSP_USING_UART2)
    if (huart->Instance == USART2)
    {
        /*##-1- Reset peripherals ##################################################*/
        __HAL_RCC_USART2_FORCE_RESET();
        __HAL_RCC_USART2_RELEASE_RESET();

        /*##-2- Disable peripherals and GPIO Clocks #################################*/
        /* Configure UART Tx as alternate function  */
        HAL_GPIO_DeInit(USART2_TX_GPIO_PORT, USART2_TX_PIN);
        /* Configure UART Rx as alternate function  */
        HAL_GPIO_DeInit(USART2_RX_GPIO_PORT, USART2_RX_PIN);

        HAL_NVIC_DisableIRQ(USART2_IRQn);
    }
#endif

#if defined(BSP_USING_UART3)
    if (huart->Instance == USART3)
    {
        /*##-1- Reset peripherals ##################################################*/
        __HAL_RCC_USART3_FORCE_RESET();
        __HAL_RCC_USART3_RELEASE_RESET();

        /*##-2- Disable peripherals and GPIO Clocks #################################*/
        /* Configure UART Tx as alternate function  */
        HAL_GPIO_DeInit(USART3_TX_GPIO_PORT, USART3_TX_PIN);
        /* Configure UART Rx as alternate function  */
        HAL_GPIO_DeInit(USART3_RX_GPIO_PORT, USART3_RX_PIN);

        HAL_NVIC_DisableIRQ(USART3_IRQn);
    }
#endif

#if defined(BSP_USING_LPUART1)
    if (huart->Instance == LPUART1)
    {
        /*##-1- Reset peripherals ##################################################*/
        __HAL_RCC_LPUART1_FORCE_RESET();
        __HAL_RCC_LPUART1_RELEASE_RESET();

        /*##-2- Disable peripherals and GPIO Clocks #################################*/
        /* Configure UART Tx as alternate function  */
        HAL_GPIO_DeInit(LPUART1_TX_GPIO_PORT, LPUART1_TX_PIN);
        /* Configure UART Rx as alternate function  */
        HAL_GPIO_DeInit(LPUART1_RX_GPIO_PORT, LPUART1_RX_PIN);

        HAL_NVIC_DisableIRQ(LPUART1_IRQn);
    }
#endif
}
